//
//  PPNetworkHelper.m
//  PPNetworkHelper
//
//  Created by AndyPang on 16/8/12.
//  Copyright © 2016年 AndyPang. All rights reserved.
//


#import "PPNetworkHelper.h"
#import "AFNetworking.h"
#import "AFNetworkActivityIndicatorManager.h"

#import "AESCrypt.h"

#import "DLayout.h"
#import "CommonCrypto/CommonDigest.h"

//#import "YYCache.h"


#ifdef DEBUG
#define PPLog(...) NSLog(@"%s 第%d行 \n %@\n\n",__func__,__LINE__,[NSString stringWithFormat:__VA_ARGS__])
#else
#define PPLog(...)
#endif


@implementation PPNetworkHelper

static NetworkStatus _status;
static BOOL _isNetwork;

#pragma mark - 开始监听网络
+ (void)startMonitoringNetwork
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status)
        {
            case AFNetworkReachabilityStatusUnknown:
                _status ? _status(PPNetworkStatusUnknown) : nil;
                _isNetwork = NO;
                PPLog(@"未知网络");
                break;
            case AFNetworkReachabilityStatusNotReachable:
                _status ? _status(PPNetworkStatusNotReachable) : nil;
                _isNetwork = NO;
                PPLog(@"无网络");
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN:
                _status ? _status(PPNetworkStatusReachableViaWWAN) : nil;
                _isNetwork = YES;
                PPLog(@"手机自带网络");
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                _status ? _status(PPNetworkStatusReachableViaWiFi) : nil;
                _isNetwork = YES;
                PPLog(@"WIFI");
                break;
        }
    }];
    
    [manager startMonitoring];
    
}

+ (void)checkNetworkStatusWithBlock:(NetworkStatus)status
{
    status ? _status = status : nil;
}

+ (BOOL)currentNetworkStatus
{
    return _isNetwork;
}

+ (void)uploadPictureWithImage:(UIImage *)image success:(HttpRequestSuccess)successBlock failL:(HttpRequestFailed)failBlock {
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html",@"text/json", @"text/javascript", nil];

}

+ (NSString *)parameters:(NSDictionary *)parameters {
    
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:&error];
    
    NSString *jsonString;
    
    if (!jsonData) {
        
        NSLog(@"jsonDataError:%@",error);
        
    }else {
        
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        
    }
    
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    
    NSRange range = {0,jsonString.length};
    
    //去掉字符串中的空格
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    
    NSRange range2 = {0,mutStr.length};
    
    //去掉字符串中的换行符
    
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    
    NSString *str = [AESCrypt encrypt:mutStr password:@"qqqqqqqq"];
    
    return str;
    
}


#pragma mark - GET请求无缓存

+ (NSURLSessionTask *)GET:(NSString *)URL
               parameters:(NSDictionary *)parameters
                  success:(HttpRequestSuccess)success
                  failure:(HttpRequestFailed)failure
{
    
    return [self GET:URL parameters:parameters responseCache:nil success:success failure:failure];
    
}


#pragma mark - POST请求无缓存

+ (NSURLSessionTask *)POST:(NSString *)URL
                parameters:(NSDictionary *)parameters
                   success:(HttpRequestSuccess)success
                   failure:(HttpRequestFailed)failure
{
    return [self POST:URL parameters:parameters responseCache:nil success:success failure:failure];

}


#pragma mark - GET请求自动缓存

+ (NSURLSessionTask *)GET:(NSString *)URL
               parameters:(NSDictionary *)parameters
            responseCache:(HttpRequestCache)responseCache
                  success:(HttpRequestSuccess)success
                  failure:(HttpRequestFailed)failure
{
    //读取缓存
//    responseCache ? responseCache([PPNetworkCache getHttpCacheForKey:URL]) : nil;
    
    AFHTTPSessionManager *manager = [self createAFHTTPSessionManager];
    return [manager GET:URL parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        success ? success(responseObject) : nil;
        //对数据进行异步缓存
//        responseCache ? [PPNetworkCache saveHttpCache:responseObject forKey:URL] : nil;
        
        NSDictionary *dictData = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
        
        PPLog(@"responseObject = %@\ndictData=%@",responseObject, dictData);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        failure ? failure(error) : nil;
        PPLog(@"error = %@",error);
        
    }];

}

#pragma mark - POST请求自动缓存

+ (NSURLSessionTask *)POST:(NSString *)URL
                parameters:(NSDictionary *)parameters
             responseCache:(HttpRequestCache)responseCache
                   success:(HttpRequestSuccess)success
                   failure:(HttpRequestFailed)failure
{
    //读取缓存
//    responseCache ? responseCache([PPNetworkCache getHttpCacheForKey:URL]) : nil;
    
    NSMutableDictionary *p = nil;
    
    if (parameters) {
        
        p = [NSMutableDictionary dictionaryWithDictionary:parameters];
        
    }else {
        
        p = [NSMutableDictionary dictionary];
        
    }
    
    // 签证
    NSString *mySign = [PPNetworkHelper getSign:p[@"json"]];
    
    [p setObject:mySign forKey:@"json"];
    
    NSString *jsonString = [NSString stringWithFormat:@"%@",[p objectForKey:@"json"]];
    
    [p removeAllObjects];
    
    [p setObject:jsonString forKey:@"json"];
 
    NSString *url = [ebaseURL stringByAppendingString:URL];
    
    AFHTTPSessionManager *manager = [self createAFHTTPSessionManager];
    
    NSLog(@"请求接口：%@", url);

    return [manager POST:url parameters:p progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
        
        NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSLog(@"数据请求成功:%@", string);
        
        success ? success(dict) : nil;
        
        //对数据进行异步缓存
//        responseCache ? [PPNetworkCache saveHttpCache:responseObject forKey:URL] : nil;
        
        NSLog(@"接口请求成功，返回的数据:%@", dict);
        
    
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        failure ? failure(error) : nil;
        PPLog(@"error = %@",error);
        
    }];
    
}

+ (NSString *)getSign:(NSString *)str {
    
    NSString *signStr = @"";
    
    str = [str stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];
    
    str = [str stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    
    str = [str stringByReplacingOccurrencesOfString:@"\t" withString:@""];
    
    //将传进来的字符串变成字典
    //    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]];
    
    NSMutableDictionary *dict = nil;
    
    if (str) {
        
        dict = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]];
        
    }else {
        
        dict = [NSMutableDictionary dictionary];
        
    }
    
    NSString *timestamp = [PPNetworkHelper getNowDateInterval];
    [dict setObject:timestamp forKey:@"timestamp"];
    NSDictionary *infoDictionary = [[NSBundle mainBundle]infoDictionary];
    NSString *versionString = [NSString stringWithFormat:@"%@",[infoDictionary objectForKey:@"CFBundleShortVersionString"]];
    [dict setObject:versionString forKey:@"version"];
    [dict setObject:@"iOS" forKey:@"system"];
    [dict setObject:[CommonUserInfo sharedInstance].isLogin ? [RSA encryptString:[CommonUserInfo sharedInstance].user_id publicKey:PublicKey] : [RSA encryptString:@"0" publicKey:PublicKey] forKey:@"user_id"];
    [dict setObject:[CommonUserInfo sharedInstance].isLogin ? [RSA encryptString:[CommonUserInfo sharedInstance].user_id publicKey:PublicKey] : [RSA encryptString:@"0" publicKey:PublicKey] forKey:@"userid"];
    NSString *device = [DLayout phoneVersion];
    [dict setObject:device forKey:@"device"];
    
    // 字典排序 并 拼接成  key=value&key=value
    NSString *paramStr = [PPNetworkHelper queryBySortedKeysWithDictionary:dict];
    
    
    // MD5 加密
    signStr = [PPNetworkHelper md5:paramStr];
    signStr = [signStr lowercaseString];
    
    //将签证拼接到最后
    [dict setObject:signStr forKey:@"sign"];
    
    //将字典转化为json格式传回去
    NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
    NSString *jsonStr = [[NSString alloc]initWithData:data encoding:(NSUTF8StringEncoding)];
    
    return jsonStr;
}

- (BOOL)isBlankString:(NSString *)aStr {
    if (!aStr) {
        return YES;
    }
    if ([aStr isKindOfClass:[NSNull class]]) {
        return YES;
    }
    if (!aStr.length) {
        return YES;
    }
    NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSString *trimmedStr = [aStr stringByTrimmingCharactersInSet:set];
    if (!trimmedStr.length) {
        return YES;
    }
    return NO;
}


#pragma mark - 获取当前时间的时间戳  本地时间和 获取时间存在时间差
+ (NSString *)getNowDateInterval {
    
    NSDate *date = [NSDate date];
    long timeSp = (long)[date timeIntervalSince1970];
    
    return [NSString stringWithFormat:@"%ld",(long)timeSp];
    
}

+ (NSString *)queryBySortedKeysWithDictionary:(NSDictionary *)dict {
    
    NSMutableArray * parameters = [NSMutableArray array];
    
    for (id key in [[dict allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)])
    {
        
        NSString * value = [NSString stringWithFormat:@"%@", dict[key]];
        
        [parameters addObject:[NSString stringWithFormat:@"%@=%@", key, value]];
        
    }
    
    return [parameters componentsJoinedByString:@"&"];
    
}

/**
 *  MD5加密
 */
+ (NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];//转换成utf-8
    unsigned char result[16];//开辟一个16字节（128位：md5加密出来就是128位/bit）的空间（一个字节=8字位=8个二进制数）
    CC_MD5( cStr, strlen(cStr), result);
    /*
     extern unsigned char *CC_MD5(const void *data, CC_LONG len, unsigned char *md)官方封装好的加密方法
     把cStr字符串转换成了32位的16进制数列（这个过程不可逆转） 存储到了result这个空间中
     */
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
    /*
     x表示十六进制，%02X  意思是不足两位将用0补齐，如果多余两位则不影响
     NSLog("%02X", 0x888);  //888
     NSLog("%02X", 0x4); //04
     */
    
}



#pragma mark - 上传图片文件

+ (NSURLSessionTask *)uploadWithURL:(NSString *)URL
                         parameters:(NSDictionary *)parameters
                             images:(NSArray<UIImage *> *)images
                               name:(NSString *)name
                           fileName:(NSString *)fileName
                           mimeType:(NSString *)mimeType
                           progress:(HttpProgress)progress
                            success:(HttpRequestSuccess)success
                            failure:(HttpRequestFailed)failure
{
    
    AFHTTPSessionManager *manager = [self createAFHTTPSessionManagerShared];
    return [manager POST:URL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {

        [images enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) {

            NSData *imageData = UIImageJPEGRepresentation(image, 0.2);
            
            [formData appendPartWithFileData:imageData name:name fileName:[NSString stringWithFormat:@"%@.%@",fileName,mimeType?mimeType:@"jpeg"] mimeType:[NSString stringWithFormat:@"image/%@",mimeType?mimeType:@"jpeg"]];

        }];
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        //上传进度
        progress ? progress(uploadProgress) : nil;
        
        PPLog(@"progress = %@",uploadProgress);
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
         NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];
        
        success ? success(dic) : nil;

        PPLog(@"上传成功 = %@",responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        failure ? failure(error) : nil;
        PPLog(@"上传失败 = %@",error);
    
    }];

}


#pragma mark - 下载文件
+ (NSURLSessionTask *)downloadWithURL:(NSString *)URL
                              fileDir:(NSString *)fileDir
                             progress:(HttpProgress)progress
                              success:(void(^)(NSString *))success
                              failure:(HttpRequestFailed)failure
{
    AFHTTPSessionManager *manager = [self createAFHTTPSessionManager];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        //下载进度
        progress ? progress(downloadProgress) : nil;
        PPLog(@"下载进度:%.2f%%",100.0*downloadProgress.completedUnitCount/downloadProgress.totalUnitCount);
        
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        
        //拼接缓存目录
        NSString *downloadDir = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileDir ? fileDir : @"Download"];
        //打开文件管理器
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        //创建Download目录
        [fileManager createDirectoryAtPath:downloadDir withIntermediateDirectories:YES attributes:nil error:nil];
        
        //拼接文件路径
        NSString *filePath = [downloadDir stringByAppendingPathComponent:response.suggestedFilename];
        
        PPLog(@"downloadDir = %@",downloadDir);
        
        //返回文件位置的URL路径
        return [NSURL fileURLWithPath:filePath];
        
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        
        success ? success(filePath.absoluteString /** NSURL->NSString*/) : nil;
        failure && error ? failure(error) : nil;
        
    }];
    
    //开始下载
    [downloadTask resume];
    
    return downloadTask;
    
}


#pragma mark - 设置AFHTTPSessionManager相关属性

+ (AFHTTPSessionManager *)createAFHTTPSessionManager
{
    //打开状态栏的等待菊花
    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    //设置请求参数的类型:HTTP (AFJSONRequestSerializer,AFHTTPRequestSerializer)
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    //设置请求的超时时间
    manager.requestSerializer.timeoutInterval = 30.f;
    //设置服务器返回结果的类型:JSON (AFJSONResponseSerializer,AFHTTPResponseSerializer)
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json",
                                                                              @"text/html",
                                                                              @"text/json",
                                                                              @"text/plain",
                                                                              @"text/javascript",
                                                                              @"text/xml",
                                                                              @"image/*"]];
    return manager;
}


+ (AFHTTPSessionManager *)createAFHTTPSessionManagerShared
{
    //打开状态栏的等待菊花
    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    //设置请求参数的类型:HTTP (AFJSONRequestSerializer,AFHTTPRequestSerializer)
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    //设置请求的超时时间
    manager.requestSerializer.timeoutInterval = 30.f;
    //设置服务器返回结果的类型:JSON (AFJSONResponseSerializer,AFHTTPResponseSerializer)
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json",
                                                                            
                                                                              @"text/html",
                                                                              @"text/json",
                                                                              @"text/plain",
                                                                              @"text/javascript",
                                                                              @"text/xml",
                                                                               @"application/octet-stream",
                                                                        
                                                                              @"image/*"]];
    
    
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
    
    securityPolicy.allowInvalidCertificates = YES;
    securityPolicy.validatesDomainName = NO;
    
    manager.securityPolicy = securityPolicy;
    
    return manager;
    
}


@end
